package cn.fscode.code.generator.controller;

import cn.fscode.code.generator.gen.*;
import cn.fscode.code.generator.model.po.DatasourceConfigPO;
import cn.fscode.code.generator.model.req.DatasourceConfigQueryReq;
import cn.fscode.code.generator.model.req.DbTableReq;
import cn.fscode.code.generator.model.resp.DatasourceResp;
import cn.fscode.code.generator.service.DatasourceConfigService;
import cn.fscode.commons.core.response.Resp;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author shenguangyang
 */
@RestController
@RequestMapping("/api/dataSource")
@RequiredArgsConstructor
public class DatasourceConfigController {
    private final DatasourceConfigService datasourceConfigService;

    @PostMapping("/add")
    public Resp<?> add(@RequestBody DatasourceConfigPO datasourceConfigPO) {
        datasourceConfigService.save(datasourceConfigPO);
        return Resp.ok();
    }

    @GetMapping("/listAll")
    public Resp<List<DatasourceResp>> listAll() {
        List<DatasourceResp> datasourceConfigList = datasourceConfigService.listAll();
        return Resp.ok(datasourceConfigList);
    }

    @GetMapping("/getById")
    public Resp<DatasourceConfigPO> getById(@RequestParam("id") Long id) {
        DatasourceConfigPO datasourceConfigPO = datasourceConfigService.getById(id);
        return Resp.ok(datasourceConfigPO);
    }

    @GetMapping("/page")
    public Resp<IPage<DatasourceConfigPO>> page(DatasourceConfigQueryReq req) {
        IPage<DatasourceConfigPO> datasourceConfigList = datasourceConfigService.page(req);
        return Resp.ok(datasourceConfigList);
    }

    @PostMapping("/update")
    public Resp<?> update(@RequestBody DatasourceConfigPO datasourceConfigPO) {
        datasourceConfigService.update(datasourceConfigPO);
        return Resp.ok();
    }

    @DeleteMapping("/delete")
    public Resp<?> delete(@RequestBody DatasourceConfigPO datasourceConfigPO) {
        datasourceConfigService.delete(datasourceConfigPO);
        return Resp.ok();
    }

    @DeleteMapping("/deleteBatch")
    public Resp<?> deleteBatch(@RequestParam("ids") List<Long> ids) {
        datasourceConfigService.deleteBatchByIds(ids);
        return Resp.ok();
    }

    @GetMapping("/listTable")
    public Resp<?> listTable(@Validated DbTableReq req) {
        List<TableDefinition> list = datasourceConfigService.listTable(req);
        return Resp.ok(list);
    }

    @RequestMapping("/testConnection")
    public Resp<?> testConnection(@RequestBody DatasourceConfigPO datasourceConfigPO) {
        String error = DBConnect.testConnection(GeneratorConfig.build(datasourceConfigPO));
        if (error != null) {
            return Resp.fail(error);
        }
        return Resp.ok();
    }

    @RequestMapping("/dbtype")
    public Resp<List<DbTypeShow>> dbType(@RequestBody DatasourceConfigPO datasourceConfigPO) {
        List<DbTypeShow> dbTypeShowList = Stream.of(DbType.values())
                .map(dbType -> new DbTypeShow(dbType.getDisplayName(), dbType.getType()))
                .collect(Collectors.toList());
        return Resp.ok(dbTypeShowList);
    }

    @Getter
    @Setter
    @AllArgsConstructor
    private static class DbTypeShow {
        private String label;
        private Integer dbType;
    }
}
